#include "StdAfx.h"
#include "Aquarium.h"


Aquarium::Aquarium(void)
// Aquariums MUST have a name and size, but I always like to have a default constructor :)
:m_name( "Aquarium" ),
 m_size_w( 10.0f ),
 m_size_h( 10.0f ),
 m_size_d( 10.0f ),
 m_fish_list(0),
 m_decoration_list(0),
 m_link_list(0),
 m_available_fish_vec(0)
{
	// TODO auto get files from directory
	m_available_fish_vec.push_back("fish_models/AngelShark.wrl");
	m_available_fish_vec.push_back("fish_models/Bandouiruka.wrl");
	m_available_fish_vec.push_back("fish_models/BlueTang.wrl");
	m_available_fish_vec.push_back("fish_models/BulueMarlin.wrl");
	m_available_fish_vec.push_back("fish_models/ClownAF.wrl");
	m_available_fish_vec.push_back("fish_models/DemeKin.wrl");
	m_available_fish_vec.push_back("fish_models/FireGoby.wrl");
	m_available_fish_vec.push_back("fish_models/GuppyBlueGrass.wrl");
	m_available_fish_vec.push_back("fish_models/Kissing.wrl");
	m_available_fish_vec.push_back("fish_models/LeopardShark.wrl");
	m_available_fish_vec.push_back("fish_models/LongBeakedBF.wrl");
	m_available_fish_vec.push_back("fish_models/Manta.wrl");
	m_available_fish_vec.push_back("fish_models/NeonTetra.wrl");
	m_available_fish_vec.push_back("fish_models/RedBetta.wrl");
	m_available_fish_vec.push_back("fish_models/Reddrum.wrl");
	m_available_fish_vec.push_back("fish_models/RedLionfish.wrl");
	m_available_fish_vec.push_back("fish_models/SaddlebackCF.wrl");
	m_available_fish_vec.push_back("fish_models/Sakuramasu.wrl");
	m_available_fish_vec.push_back("fish_models/Satukimasu.wrl");
	m_available_fish_vec.push_back("fish_models/Sayori.wrl");
	m_available_fish_vec.push_back("fish_models/Scissortail.wrl");
	m_available_fish_vec.push_back("fish_models/SiameseTiger.wrl");
	m_available_fish_vec.push_back("fish_models/ThreadfinBF.wrl");
	m_available_fish_vec.push_back("fish_models/TomatoCF.wrl");
	m_available_fish_vec.push_back("fish_models/TomatoCM.wrl");
	m_available_fish_vec.push_back("fish_models/Zatou.wrl");

	m_available_decoration_vec.push_back("decoration_models/alga.wrl");
	m_available_decoration_vec.push_back("decoration_models/castelo.wrl");
	m_available_decoration_vec.push_back("decoration_models/sushi.wrl");
}

Aquarium::Aquarium( std::string name, float size_w = 10.0f, float size_h = 10.0f, float size_d = 10.0f )
:m_name( name ),
 m_size_w( size_w ),
 m_size_h( size_h ),
 m_size_d( size_d ),
 m_fish_list(0),
 m_decoration_list(0),
 m_link_list(0),
 m_available_fish_vec(0)
{
	// TODO auto get files from directory
	m_available_fish_vec.push_back("fish_models/AngelShark.wrl");
	m_available_fish_vec.push_back("fish_models/Bandouiruka.wrl");
	m_available_fish_vec.push_back("fish_models/BlueTang.wrl");
	m_available_fish_vec.push_back("fish_models/BulueMarlin.wrl");
	m_available_fish_vec.push_back("fish_models/ClownAF.wrl");
	m_available_fish_vec.push_back("fish_models/DemeKin.wrl");
	m_available_fish_vec.push_back("fish_models/FireGoby.wrl");
	m_available_fish_vec.push_back("fish_models/GuppyBlueGrass.wrl");
	m_available_fish_vec.push_back("fish_models/Kissing.wrl");
	m_available_fish_vec.push_back("fish_models/LeopardShark.wrl");
	m_available_fish_vec.push_back("fish_models/LongBeakedBF.wrl");
	m_available_fish_vec.push_back("fish_models/Manta.wrl");
	m_available_fish_vec.push_back("fish_models/NeonTetra.wrl");
	m_available_fish_vec.push_back("fish_models/RedBetta.wrl");
	m_available_fish_vec.push_back("fish_models/Reddrum.wrl");
	m_available_fish_vec.push_back("fish_models/RedLionfish.wrl");
	m_available_fish_vec.push_back("fish_models/SaddlebackCF.wrl");
	m_available_fish_vec.push_back("fish_models/Sakuramasu.wrl");
	m_available_fish_vec.push_back("fish_models/Satukimasu.wrl");
	m_available_fish_vec.push_back("fish_models/Sayori.wrl");
	m_available_fish_vec.push_back("fish_models/Scissortail.wrl");
	m_available_fish_vec.push_back("fish_models/SiameseTiger.wrl");
	m_available_fish_vec.push_back("fish_models/ThreadfinBF.wrl");
	m_available_fish_vec.push_back("fish_models/TomatoCF.wrl");
	m_available_fish_vec.push_back("fish_models/TomatoCM.wrl");
	m_available_fish_vec.push_back("fish_models/Zatou.wrl");

	m_available_decoration_vec.push_back("decoration_models/alga.wrl");
	m_available_decoration_vec.push_back("decoration_models/castelo.wrl");
	m_available_decoration_vec.push_back("decoration_models/sushi.wrl");
}

Aquarium::~Aquarium(void)
{
}

std::string Aquarium::getName( void ) const
{
	return m_name;
}

void Aquarium::setName( const std::string name )
{
	m_name = name;
}

float Aquarium::getSizeW( void ) const
{
	return m_size_w;
}

void Aquarium::setSizeW( const float size_w )
{
	m_size_w = size_w;
}

float Aquarium::getSizeH( void ) const
{
	return m_size_h;
}

void Aquarium::setSizeH( const float size_h )
{
	m_size_h = size_h;
}

float Aquarium::getSizeD( void ) const
{
	return m_size_d;
}

void Aquarium::setSizeD( const float size_d )
{
	m_size_d = size_d;
}

void Aquarium::addFish( void )
{
	std::random_shuffle( m_available_fish_vec.begin(), m_available_fish_vec.end() );
	std::vector< std::string >::iterator it = m_available_fish_vec.begin();

	Fish rand_fish( "Random Fish", (*it), 1.0f );

	m_fish_list.push_back( rand_fish );
}

void Aquarium::addFish( const Fish &r )
{
	m_fish_list.push_back( r );
}

void Aquarium::addFish( const std::string name, const std::string model_path, const float scale )
{
	m_fish_list.push_back( Fish( name, model_path, scale ) );
}

void Aquarium::addDecoration( void )
{
	std::random_shuffle( m_available_decoration_vec.begin(), m_available_decoration_vec.end() );
	std::vector< std::string >::iterator it = m_available_decoration_vec.begin();

	Decoration rand_decoration( "Random decoration", (*it), 0, 0, 0, 0, 0, 1.0f );

	m_decoration_list.push_back( rand_decoration );
}

void Aquarium::addDecoration( const Decoration &r )
{
	m_decoration_list.push_back( r );
}

void Aquarium::addDecoration( const std::string name, const std::string model_path, const float pos_x, const float pos_y, const float pos_z, const float angle,
						      const int axis, const float scale )
{
	m_decoration_list.push_back( Decoration( name, model_path, pos_x, pos_y, pos_z, angle, axis, scale) );
}

void Aquarium::generateFiles( void )
{
	std::string filename = "aquariums/";
	filename.append( m_name );
	filename.append( ".wrl" );

	std::ofstream outputFile( filename.c_str(), std::ios::out );
	if (!outputFile) {
		std::cerr << "File cannot be opened for writtin'!\n";
		exit(1);
	}

	outputFile << "#VRML V2.0 utf8";
	// PAREDES

	// chao
	outputFile << "\n" << "Transform {";
		outputFile << "\t" << "scale " <<  m_size_w << " 0.5 " << m_size_d;
		outputFile << "\t" << "translation 0 " << -m_size_h << " 0";
		outputFile << "\t" << "children [";
			outputFile << "\t" << "Shape {";
				outputFile << "\t" <<  "appearance DEF aquarium_glass Appearance { ";
					outputFile << "\t" << "material Material {";
						outputFile << "\t" << "diffuseColor 0.0 0.7 0.8";
						outputFile << "\t" << "ambientIntensity 0.8";
						outputFile << "\t" << "transparency 0.3";
					outputFile << "\t" << "}";
				outputFile << "\t" << "}";
				outputFile << "\t" << "geometry Box {}";
			outputFile << "\t" << "}";
		outputFile << "\t" << "]";
	outputFile << "\t" << "}";

	// frente
	outputFile << "\n" << "Transform {";
		outputFile << "\t" << "scale " <<  m_size_w << " " << m_size_h << "  0.5";
		outputFile << "\t" << "translation 0 0 " << m_size_d;
		outputFile << "\t" << "children [";
			outputFile << "\t" << "Shape {";
				outputFile << "\t" <<  "appearance USE aquarium_glass";
				outputFile << "\t" << "geometry Box {}";
			outputFile << "\t" << "}";
		outputFile << "\t" << "]";
	outputFile << "\t" << "}";

	// atras
	outputFile << "\n" << "Transform {";
		outputFile << "\t" << "scale " <<  m_size_w << " " << m_size_h << "  0.5";
		outputFile << "\t" << "translation 0 0 " << -m_size_d;
		outputFile << "\t" << "children [";
			outputFile << "\t" << "Shape {";
				outputFile << "\t" <<  "appearance USE aquarium_glass";
				outputFile << "\t" << "geometry Box {}";
			outputFile << "\t" << "}";
		outputFile << "\t" << "]";
	outputFile << "\t" << "}";

	// lado direito
	outputFile << "\n" << "Transform {";
	outputFile << "\t" << "scale " << "0.5 " << m_size_h << " " << m_size_d;
		outputFile << "\t" << "translation "<< m_size_w <<" 0 0";
		outputFile << "\t" << "children [";
			outputFile << "\t" << "Shape {";
				outputFile << "\t" <<  "appearance USE aquarium_glass";
				outputFile << "\t" << "geometry Box {}";
			outputFile << "\t" << "}";
		outputFile << "\t" << "]";
	outputFile << "\t" << "}";

	// lado esquerdo
	outputFile << "\n" << "Transform {";
	outputFile << "\t" << "scale " << "0.5 " << m_size_h << " " << m_size_d;
		outputFile << "\t" << "translation "<< -m_size_w <<" 0 0";
		outputFile << "\t" << "children [";
			outputFile << "\t" << "Shape {";
				outputFile << "\t" <<  "appearance USE aquarium_glass";
				outputFile << "\t" << "geometry Box {}";
			outputFile << "\t" << "}";
		outputFile << "\t" << "]";
	outputFile << "\t" << "}";

	// topo
	outputFile << "\n" << "Transform {";
		outputFile << "\t" << "scale " <<  m_size_w << " 0.5 " << m_size_d;
		outputFile << "\t" << "translation 0 " << m_size_h - ( m_size_h/8 ) << " 0";
		outputFile << "\t" << "children [";
			outputFile << "\t" << "Shape {";
				outputFile << "\t" <<  "appearance USE aquarium_glass";
				outputFile << "\t" << "geometry Box {}";
			outputFile << "\t" << "}";
		outputFile << "\t" << "]";
	outputFile << "\t" << "}";

	// FIM DAS PAREDES

	// INICIO DAS PEDRAS
	outputFile << "\n" << "Transform {";
		outputFile << "\t" << "scale " <<  m_size_w-1 << " " << m_size_h/6 << " " << m_size_d-1;
		outputFile << "\t" << "translation 0 " << ( -m_size_h + m_size_h/6 ) << " 0";
		outputFile << "\t" << "children [";
			outputFile << "\t" << "Shape {";
				outputFile << "\t" << "appearance DEF sand Appearance { ";
					outputFile << "\t" << "texture ImageTexture {";
						outputFile << "\t" << "url \"stones.jpg\"";
					outputFile << "\t" << "}";
					outputFile << "\t" << "textureTransform TextureTransform {";
						outputFile << "\t" << "scale 0.5 0.5";
						outputFile << "\t" << "rotation 0.0";
						outputFile << "\t" << "center 0.0 0.0";
						outputFile << "\t" << "translation 0.0 0.0";
					outputFile << "\t" << "}";
				outputFile << "\t" << "}";
				outputFile << "\t" << "geometry Box {}";
			outputFile << "\t" << "}";
		outputFile << "\t" << "]";
	outputFile << "\t" << "}";
	// FIM DAS PEDRAS

	// INICIO DAS DECORACOES
	if( m_decoration_list.size() > 0 )
	{
		std::list< Decoration >::iterator it;

		for( it = m_decoration_list.begin(); it != m_decoration_list.end(); it++ )
		{
			int axis = (*it).getAxis();
			std::string real_axis = "0 0 0";

			if( axis == 1 )
				real_axis = "1 0 0";
			else if( axis == 2 )
				real_axis = "0 1 0";
			else if( axis == 3 )
				real_axis = "0 0 1";

			outputFile << "\n" << "Transform {";
			outputFile << "\t" << "scale " << (*it).getScale() * m_size_w*0.001f << " " << (*it).getScale() * m_size_w*0.001f << " " << (*it).getScale() * m_size_w*0.001f;
				outputFile << "\t" << "translation " << (*it).getPosX() << " " << -m_size_h + ( m_size_h/6 ) + (*it).getScale() * m_size_h*0.001f << " " << (*it).getPosZ();
				outputFile << "\t" << "rotation " << real_axis << " " << (*it).getAngle();
				outputFile << "\t" << "children [";
					outputFile << "\t" << "Inline {";
						outputFile << "\t" << "url \"" << (*it).getModelPath() << "\"";
					outputFile << "\t" << "}";
				outputFile << "\t" << "]";
			outputFile << "\t" << "}";
		}
	}
	// FIM DAS DECORACOES

	// INICIO DOS PEIXES

	if( m_fish_list.size() > 0 )
	{
		std::list< Fish >::iterator it;

		for( it = m_fish_list.begin(); it != m_fish_list.end(); it++ )
		{
			srand ( time(NULL) );
			int pos_x = rand() % ( int )m_size_w;
			int pos_y = rand() % ( int )m_size_h;
			int pos_z = rand() % ( int )m_size_d;

			if( pos_x > m_size_w/2 )
				pos_x = -pos_x/2;
			if( pos_y > m_size_h/2 )
				pos_y = -pos_y/2;
			if( pos_z > m_size_d/2 )
				pos_z = -pos_z/2;

			outputFile << "\n" << "Transform {";
				outputFile << "\t" << "scale " << (*it).getScale() * 10 << " " << (*it).getScale() * 10 << " " << (*it).getScale() * 10;
				outputFile << "\t" << "translation " << pos_x << " " << pos_y << " " << pos_z;
				outputFile << "\t" << "children [";
					outputFile << "\t" << "Inline {";
						outputFile << "\t" << "url \"" << (*it).getModelPath() << "\"";
					outputFile << "\t" << "}";
				outputFile << "\t" << "]";
			outputFile << "\t" << "}";
		}
	}

	// FIM DOS PEIXES
}